package com.loto.insurance.oem.web.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import com.loto.insurance.oem.web.entity.OrderFlow;
import com.loto.insurance.oem.web.enumeration.PolicyStatusEnum;
import com.loto.insurance.oem.web.db.mapper.OrderFlowMapper;
import com.loto.insurance.oem.web.db.mapper.OrderInfoExtMapper;
import com.loto.insurance.oem.web.db.mapper.OrderInfoMapper;
import com.loto.insurance.oem.web.db.mapper.PolicyFlowMapper;
import com.loto.insurance.oem.web.db.mapper.PolicyInfoAirMapper;
import com.loto.insurance.oem.web.db.mapper.PolicyInfoMapper;
import com.loto.insurance.oem.web.db.mapper.PolicyInfoTravelMapper;
import com.loto.insurance.oem.web.db.mapper.ProductInfoMapper;
import com.loto.insurance.oem.web.entity.OrderInfo;
import com.loto.insurance.oem.web.entity.OrderInfoExt;
import com.loto.insurance.oem.web.entity.ProductInfo;
import com.loto.insurance.oem.web.entity.ajax.BaseJson;
import com.loto.insurance.oem.web.entity.config.OEMConfig;
import com.loto.insurance.oem.web.enumeration.ConfigFileEnum;
import com.loto.insurance.oem.web.enumeration.ControllerPropertyEnum;
import com.loto.insurance.oem.web.enumeration.InsTypeEnum;
import com.loto.insurance.oem.web.enumeration.OrderStatusEnum;
import com.loto.insurance.oem.web.service.common.AirIns;
import com.loto.insurance.oem.web.service.common.Ins;
import com.loto.insurance.oem.web.service.common.TravelIns;
import com.loto.insurance.oem.web.utils.Config;
import com.loto.utils.DecimalUtils;
import com.loto.utils.Http;
import com.loto.utils.XML;

@Service
public class OrderInfoService {

  static Logger logger = LogManager.getLogger(OrderInfoService.class);

  @Autowired
  DataSourceTransactionManager transactionManager;

  @Autowired
  private DefaultTransactionDefinition def;

  @Autowired
  OrderInfoMapper orderInfoMapper;

  @Autowired
  OrderInfoExtMapper orderInfoExtMapper;

  @Autowired
  ProductInfoMapper productInfoMapper;

  @Autowired
  OrderFlowMapper orderFlowMapper;

  @Autowired
  PolicyFlowMapper policyFlowMapper;

  @Autowired
  PolicyInfoAirMapper policyInfoAirMapper;

  @Autowired
  PolicyInfoTravelMapper policyInfoTravelMapper;

  @Autowired
  PolicyInfoMapper policyInfoMapper;

  @Autowired
  AirIns airIns;

  @Autowired
  TravelIns travelIns;

  public ArrayList<OrderInfo> findAllOrdersByCust(Map<String, Object> params) {
	ArrayList<OrderInfo> orderList = orderInfoMapper
	    .findAllOrdersByCustPager(params);
	return orderList;
  }

  public long findAllOrdersByCustCount(Map<String, Object> params) {
	return orderInfoMapper.findAllOrdersByCustPagerCount(params);
  }

  public ArrayList<String> findInsCompanyByCust(long custId) {
	return orderInfoMapper.findInsCompanyByCust(custId);
  }

  public BaseJson createOrder(ArrayList<String> arrList, long productId,
	  long custId, String custName) {
	BaseJson base = new BaseJson();
	String msg;
	try {
	  msg = insertOrderData(arrList, productId, custId, custName);
	} catch (Exception e) {
	  e.printStackTrace();
	  msg = null;
	}
	if (msg != null && !msg.isEmpty() && DecimalUtils.isDecimal(msg)) {
	  base.setOk(true);
	} else {
	  base.setOk(false);
	}
	base.setMsg(msg);
	return base;
  }

  private String insertOrderData(ArrayList<String> arrList, long productId,
	  long custId, String custName) {
	Map<String, Object> params = new HashMap<String, Object>();
	params.put("custId", custId);
	params.put("productId", productId);
	ProductInfo productInfo = productInfoMapper.findProductInfoById(params);

	if (productInfo != null) {
	  Ins ins = null;
	  int typeFid = productInfo.getProductTypeFid();
	  if (typeFid == InsTypeEnum.AIR.getIndex()) {
		ins = airIns;
	  } else if (typeFid == InsTypeEnum.TRAVEL.getIndex()) {
		ins = travelIns;
	  }
	  if (ins != null)
		return ins.insertOrder(productInfo, arrList, custId, custName);
	  else
		return ControllerPropertyEnum.ORDER_INPUT_ERR.toString();
	}
	return ControllerPropertyEnum.ORDER_INPUT_WRONG.toString();
  }

  public OrderInfo findOrderPayInfoByCust(long orderId, long custId) {
	Map<String, Object> params = new HashMap<String, Object>();
	params.put("custId", custId);
	params.put("orderId", orderId);
	return orderInfoMapper.findOrderPayInfoByCust(params);
  }

  public OrderInfo findOrderInfoById(long orderId, long custId) {
	Map<String, Object> params = new HashMap<String, Object>();
	if (custId > 0)
	  params.put("custId", custId);
	params.put("orderId", orderId);
	return orderInfoMapper.findOrderInfoById(params);
  }

  public OrderInfoExt findOrderInfoExtById(long orderId) {
	return orderInfoExtMapper.findOrderInfoExtById(orderId);
  }

  public BaseJson cancelOrder(long orderId, long custId) {
	BaseJson base = new BaseJson();
	base.setOk(false);
	String msg = null;

	// 取得订单信息，比对状态
	OrderInfo orderInfo = findOrderInfoById(orderId, custId);
	if (orderInfo != null
	    && orderInfo.getOrderStatusFid() == OrderStatusEnum.UNPAY.getIndex()) {
	  TransactionStatus status = transactionManager.getTransaction(def);
	  try {
		// TODO 通知大后台
		Config config = new Config();
		OEMConfig configFile = config.getConfigFile(ConfigFileEnum.OEMCONFIG,
		    OEMConfig.class);

		com.loto.insurance.oem.web.entity.webservice.SimpleOrderInfo requestOrderInfo = new com.loto.insurance.oem.web.entity.webservice.SimpleOrderInfo();
		requestOrderInfo.setOrderId(orderId);
		;
		requestOrderInfo.setOrderProductTypeFid(orderInfo
		    .getOrderProductTypeFid());
		requestOrderInfo.setOrderCustFid(custId);

		String xmlRequest = XML.toXML(requestOrderInfo,
		    com.loto.insurance.oem.web.entity.webservice.SimpleOrderInfo.class);
		logger.info(xmlRequest);
		Map<String, String> paramMap = new HashMap<String, String>();
		paramMap.put("content", xmlRequest);
		String xmlResponse = Http.doPost(configFile.getOemPlatform()
		    + "/webservice/cancelorder.service", paramMap);
		logger.info(xmlResponse);
		BaseJson response = XML.fromXML(xmlResponse, BaseJson.class);
		if (response != null && response.isOk()) {
		  // 修改订单状态
		  HashMap<String, Object> params = new HashMap<String, Object>();
		  params.put("orderId", orderId);
		  params.put("orderStatusFid", OrderStatusEnum.CANCELED.getIndex());
		  orderInfoMapper.updateOrderStatusById(params);

		  // 创建订单流
		  OrderFlow orderFlow = new OrderFlow();
		  orderFlow.setFlowOrderFid(orderId);
		  orderFlow.setFlowOperFid(0);
		  orderFlow.setFlowOrderStatusFid(OrderStatusEnum.CANCELED.getIndex());
		  orderFlow.setFlowOrderStatus(OrderStatusEnum.CANCELED.getName());
		  orderFlow.setFlowMemo(OrderStatusEnum.CANCELED.getDesc());
		  orderFlowMapper.insertOrderFlow(orderFlow);

		  // 修改保单状态为取消
		  Map<String, Object> statusParams = new HashMap<String, Object>();
		  statusParams.put("orderId", orderId);
		  statusParams.put("statusId", PolicyStatusEnum.CANCELED.getIndex());

		  Map<String, Object> policyParams = new HashMap<String, Object>();
		  policyParams.put("orderId", orderId);
		  policyParams
			  .put("flowInsTypeFid", orderInfo.getOrderProductTypeFid());
		  policyParams.put("flowPolicyStatusFid",
			  PolicyStatusEnum.CANCELED.getIndex());
		  policyParams.put("flowPolicyStatus",
			  PolicyStatusEnum.CANCELED.getName());
		  policyParams.put("flowFeeFlowFid", 0);
		  policyParams.put("flowMemo", PolicyStatusEnum.CANCELED.getDesc());
		  if (orderInfo.getOrderProductTypeFid() == InsTypeEnum.AIR.getIndex()) {
			policyInfoAirMapper.updatePolicyStatusByOrderId(statusParams);
			// 批量创建保单流
			policyFlowMapper.insertAirPolicyFlowBat(policyParams);
		  } else if (orderInfo.getOrderProductTypeFid() == InsTypeEnum.TRAVEL
			  .getIndex()) {
			policyInfoTravelMapper.updatePolicyStatusByOrderId(statusParams);
			// 批量创建保单流
			policyFlowMapper.insertTravelPolicyFlowBat(policyParams);
		  }
		  transactionManager.commit(status);
		  base.setOk(true);
		} else {
		  msg = ControllerPropertyEnum.ORDER_DATA_WRONG.toString();
		}
	  } catch (Exception e) {
		e.printStackTrace();
		transactionManager.rollback(status);
		msg = null;
	  }
	} else
	  msg = ControllerPropertyEnum.ORDER_DATA_WRONG.toString();
	base.setMsg(msg);
	return base;
  }

  public ArrayList<OrderInfo> findAllOrders(Map<String, Object> params) {
	ArrayList<OrderInfo> orderList = orderInfoMapper.findAllOrdersPager(params);
	return orderList;
  }

  public long findAllOrdersCount(Map<String, Object> params) {
	return orderInfoMapper.findAllOrdersPagerCount(params);
  }

  public ArrayList<String> findInsCompany() {
	return orderInfoMapper.findInsCompany();
  }
}
